﻿#region License

// Copyright (c) 2012, Zhiyong Yang.
// All rights reserved.
// 
// 
// This software is licensed under the GNU General Public License version 2 (GPLv2).
// 
// Contact Me: 
//  Mail: younthu@yahoo.com.cn
//  MSN:  evil_eve_live@hotmail.com

#endregion


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Practices.Prism.ViewModel;
using BubbelsModel;
using System.Collections.ObjectModel;
using Bubbels.VM;

namespace Bubbels
{
    public class BubbelsVM:NotificationObject
    {
        private BubbelsTable model = null;
        private int score = 0;
        public int Score
        {
            get
            { 
                return score; 
            }

            set {
                score = value;
                this.RaisePropertyChanged("Score");
            }
        }

        private int column;
        public int Column {
            get {
                return column;
            }
            set {
                column = value;
                this.RaisePropertyChanged("Column");
            }
        }

        private int unionScore = 0;
        public int UnionScore
        {
            get
            {
                return unionScore;
            }
            set {
                unionScore = value;
                this.RaisePropertyChanged("UnionScore");
            }
        }
        private int row;
        public int Row
        {
            get
            {
                return row;
            }
            set
            {
                row = value;
                this.RaisePropertyChanged("Row");
            }
        }

        private bool gameOver = false;
        public bool GameOver
        {
            get { return gameOver; }
            set {
                gameOver = value;
                this.RaisePropertyChanged("GameOver");
            }
        }
        public int Seed{get;set;}
        public ObservableCollection<BallVM> Balls { get; set; }
        public BubbelsVM(int column, int row):this(column,row, (int)DateTime.Now.Ticks)
        {
        }
        public BubbelsVM(int column, int row, int seed)
        {
            this.Balls = new ObservableCollection<BallVM>();
            Seed = seed;
            this.Column = column;
            this.Row = row;
            this.model = new BubbelsTable(column, row,seed);
            this.model.OnBallCleared += (rowIndex, colIndex) =>
                {

                    var ball = this.Balls.Single(vm => { return vm.IsAliveAt(rowIndex,colIndex); });
                    ball.Removed = true;
                    
                    //
                };
            this.model.OnBallMoveVertical += (rowIndex, colIndex,delta) =>
            {

                this.Balls.Single(vm => { return vm.IsAliveAt(rowIndex, colIndex); }).MoveVertical(delta);
            };

            this.model.OnBallMoveHorizontal += (rowIndex, colIndex,delta) =>
                {


                    var ball = this.Balls.Single(vm => { return vm.IsAliveAt(rowIndex,colIndex); });
                        if (null != ball) ball.MoveHorizontal( delta);
                  
                       
                    
                };

            this.model.OnNewBall += (ball) =>
                {
                    BallVM vm = new BallVM();
                    vm.Column = ball.X;
                    vm.Row = ball.Y;
                    vm.BallType = (BallType) ball.Type;
                    this.Balls.Add(vm);
                };

        }


        public void FillTable()
        {
            this.model.FillTable();

        }
        public event Action<BallVM> OnNewBall = delegate { };

        public void BallPressed(int col, int row)
        { 

        }

        public BallType GetBall(int col, int row)
        {
            return (BallType)model.GetBall(col, row);
        }

        public List<Ball> GetUnion(int col, int row)
        {
            return this.model.GetUnion(col, row);
        }

        public void ColorUnion(int col, int row)
        {
            // Clear balls' color
            foreach (var item in this.Balls)
            {
                item.Selected = false;
            }

            // Coloring balls
            var balls = GetUnion(col, row);
            if (balls.Count <=1)
            {
                this.UnionScore = 0;
                return;
            }
            this.UnionScore = balls.Count * balls.Count;

            foreach (var item in balls)
            {
                this.Balls.Single((ballVM) => { return ballVM.IsAliveAt(item.Y,item.X ); }).Selected = true;
            }
        }
        public List<Ball> ClearUnion(int col, int row)
        {
            var balls=  this.model.ClearUnion(col, row);
            if (balls.Count > 1)
            {
                this.Score += balls.Count * balls.Count;
            }
            return balls;
        }

        internal bool IsGameOver()
        {
            this.GameOver= this.model.IsGameOver();
            return this.GameOver;
        }

        public void GabageCollect()
        {
            for (int i = Balls.Count-1; i >=0; i--)
            {
                if (Balls[i].Removed)
                {
                    Balls.RemoveAt(i);
                }
            }
        }

        public void ResetDelta()
        {
            foreach (var item in this.Balls)
            {
                item.ClearDelta();
            }
        }
    }
}
